package com.cnt.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.cnt.dao.*;
import com.cnt.entity.*;
import com.cnt.service.FundService;
import com.cnt.util.FileUtil;
import com.cnt.vo.ResultVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class FundServiceImpl implements FundService {

    private static String IMAGE_DIR = "src/main/resources/static/image/fundImage";

    @Autowired
    private FundRaiseDao fundRaiseDao;
    @Autowired
    private ActivityFundDao activityFundDao;
    @Autowired
    private RequestReliefDao requestReliefDao;
    @Autowired
    private FileUtil fileUtil;

    @Override
    public ResultVo<String> donation(FundRaise fundRaise) {
        fundRaise.setTime(new Date());
        int i = fundRaiseDao.insert(fundRaise);
        if (i != 1) return new ResultVo<>(1, "系统繁忙，稍后再试", null);
        LambdaUpdateWrapper<ActivityFund> luw = new LambdaUpdateWrapper<>();
        luw.eq(ActivityFund::getActivityFundId, 1)
                .setSql("money = money + " + fundRaise.getAmount());
        activityFundDao.update(null, luw);
        return new ResultVo<>(0, "捐赠成功", null);
    }

    @Override
    public ResultVo<ActivityFund> getActivityFund(Integer activityFundId) {
        return new ResultVo<>(0, "查询成功", activityFundDao.selectById(activityFundId));
    }

    @Override
    public ResultVo<List<FundRaise>> getFundRaise(Integer userId) {
        LambdaQueryWrapper<FundRaise> lqw = new LambdaQueryWrapper<>();
        lqw.eq(userId != 0, FundRaise::getUserId, userId);
        List<FundRaise> fundRaiseList = fundRaiseDao.selectList(lqw);
        return new ResultVo<>(0, "查询成功", fundRaiseList);
    }

    @Override
    public ResultVo<List<RequestRelief>> getRequestReliefList(Integer userId) {
        LambdaQueryWrapper<RequestRelief> lqw = new LambdaQueryWrapper<>();
        lqw.eq(userId != 0, RequestRelief::getUserId, userId);
        lqw.eq(RequestRelief::getOpinion, "同意");
        List<RequestRelief> requestReliefList = requestReliefDao.selectList(lqw);
        return new ResultVo<>(0, "查询成功", requestReliefList);
    }

    @Override
    public ResultVo<String> createRequest(RequestRelief requestRelief) {
        int i = requestReliefDao.insert(requestRelief);
        if (i != 1) return new ResultVo<>(1, "系统繁忙，稍后再试", null);
        return new ResultVo<>(0, "捐赠成功", null);
    }

    @Override
    public InputStream downloadUsedFile(Integer requestReliefId) {
        RequestRelief requestRelief = requestReliefDao.selectById(requestReliefId);
        return new ByteArrayInputStream(requestRelief.getUsedFile());
    }

    @Override
    public ResultVo<String> uploadUsedFile(Integer requestReliefId, MultipartFile file) {
        // 校验上传的文件大小
        long size = file.getSize();
        if (size > 16 * 1024 * 1024) { // 限制文件大小为16MB
            return new ResultVo<>(4, "文件大小不能超过16MB", null);
        }
        String contentType = file.getContentType();
        RequestRelief requestRelief = requestReliefDao.selectById(requestReliefId);
        try {
            File toFile = fileUtil.convertMultipartFileToFile(file);
            if (contentType != null) {
                if (contentType.equals("application/msword") || contentType.equals("application/vnd.openxmlformats-officedocument.wordprocessingml.document")) {
                    File toPdf = fileUtil.convertToPdf(toFile);
                    byte[] bytes = fileUtil.addWatermarkToPDF(toPdf, "捐赠平台专用");
                    requestRelief.setUsedFile(bytes);
                } else if (contentType.equals("application/pdf")) {
                    byte[] bytes = fileUtil.addWatermarkToPDF(toFile, "捐赠平台专用");
                    requestRelief.setUsedFile(bytes);
                } else {
                    return new ResultVo<>(2, "文件不是word或者pdf类型，上传失败", null);
                }
            } else {
                return new ResultVo<>(3, "文件未知类型，上传失败", null); // 未知类型
            }
            toFile.delete();
        } catch (Exception e) {
            e.printStackTrace();
        }
        requestRelief.setIsFile(1);
        int i = requestReliefDao.updateById(requestRelief);
        if (i != 1) return new ResultVo<>(1, "系统繁忙，请稍后再试", null);
        return new ResultVo<>(0, "资料上传成功", null);
    }

    @Override
    public ResultVo<String> uploadActivityFundImage(Integer activityFundId, MultipartFile file) {
        // 校验上传的文件大小
        long size = file.getSize();
        if (size > 16 * 1024 * 1024) { // 限制文件大小为16MB
            return new ResultVo<>(2, "图片大小不能超过16MB", null);
        }
        ActivityFund activityFund = activityFundDao.selectById(activityFundId);
        // 生成文件名
        String filename = "activityFund_" + activityFundId + "_Img.jpg";

        // 保存文件到服务器 若文件名一样覆盖式写入
        Path targetPath = Paths.get(IMAGE_DIR, filename);
        try {
            Files.copy(file.getInputStream(), targetPath, StandardCopyOption.REPLACE_EXISTING);
        } catch (IOException e) {
            e.printStackTrace();
        }
        activityFund.setImage("localhost:8888/image/donationImg/" + filename);
        int i = activityFundDao.updateById(activityFund);
        if (i != 1) return new ResultVo<>(1, "系统繁忙，请稍后再试", null);
        try {
            Runtime.getRuntime().exec("mvn.cmd clean package");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new ResultVo<>(0, "图片更新成功", null);
    }

    @Override
    public ResultVo<String> examineRequestFund(RequestRelief requestRelief) {
        int i = requestReliefDao.updateById(requestRelief);
        if (i != 1) return new ResultVo<>(1, "系统繁忙，稍后再试", null);
        return new ResultVo<>(0, "审核成功", null);
    }

    @Override
    public ResultVo<List<RequestRelief>> getMyRequestReliefList(Integer userId) {
        LambdaQueryWrapper<RequestRelief> lqw = new LambdaQueryWrapper<>();
        lqw.eq(RequestRelief::getUserId, userId);
        List<RequestRelief> requestReliefList = requestReliefDao.selectList(lqw);
        return new ResultVo<>(0, "查询成功", requestReliefList);
    }

    @Override
    public ResultVo<List<Object>> getUserNumbers() {
        List<Object> list = new ArrayList<>();
        ActivityFund activityFund = activityFundDao.selectById(1);
        Date time = activityFund.getTime();
        list.add(time);
        double fundedAmount = activityFund.getFundedAmount();
        double expenseAmount = activityFund.getExpenseAmount();
        list.add(fundedAmount);
        list.add(expenseAmount);
        LambdaUpdateWrapper<RequestRelief> luw = new LambdaUpdateWrapper<>();
        luw.eq(RequestRelief::getOpinion, "通过");
        Integer count = requestReliefDao.selectCount(luw);
        list.add(count);
        return new ResultVo<>(0, "查询成功", list);
    }

    @Override
    public ResultVo<List<Object>> getAdminNumbers() {
        List<Object> list = new ArrayList<>();
        ActivityFund activityFund = activityFundDao.selectById(1);
        double fundedAmount = activityFund.getFundedAmount();
        list.add(fundedAmount);
        double remainderAmount = fundedAmount - activityFund.getExpenseAmount();
        list.add(remainderAmount);
        LambdaQueryWrapper<RequestRelief> lqw = new LambdaQueryWrapper<>();
        lqw.and(wrapper -> wrapper.eq(RequestRelief::getOpinion, "").or().isNull(RequestRelief::getOpinion));
        List<RequestRelief> requestReliefList = requestReliefDao.selectList(lqw);
        int count = requestReliefList.size();
        list.add(count);
        double amount = 0;
        for (RequestRelief requestRelief : requestReliefList) {
            amount += requestRelief.getReliefMoney();
        }
        list.add(amount);
        return new ResultVo<>(0, "查询成功", list);
    }


}
